home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Games of Daze
/
Infomagic - Games of Daze (Summer 1995) (Disc 1 of 2).iso
/
x2ftp
/
msdos
/
libs
/
knowhow4
/
basica.cpp
< prev
next >
Wrap
C/C++ Source or Header
|
1994-11-03
|
8KB
|
400 lines
#include "slang.h"
#include "nret.h"
//////////////////////////
int Slang::get_argument(double* x)
{
/* get_token(); // line argument
if(token_type != VARIABLE && token_type != NUMBER
&& token_type != COMMAND && token[0] != '-')
return 1;
putback();
*/
get_exp(x);
return 0;
}
////////////////////////////////
char* Slang::get_exp(double* result)
{
if(error)
return NULL;
char* str_value;
get_token();
if(!*token)
{ serror(2); return NULL; }
str_value = level2(result);
return str_value;
}
////////////////////////
char* Slang::level2(double* result)
{
if(error)
return NULL;
char op; char* str_value;
double hold;
str_value = level3(result);
while((op = *token) == '+' || op == '-')
{
get_token();
str_value = level3(&hold); // str_value = !!!
arith(op, result, &hold);
}
return str_value;
}
//////////////////////////
char* Slang::level3(double* result)
{
if(error)
return NULL;
register char op; char* str_value;
double hold;
str_value = level4(result);
while((op = *token) == '*' || op == '/' || op == '%')
{
get_token();
str_value = level4(&hold); // str_value = !!!
arith(op, result, &hold);
}
return str_value;
}
//////////////////////////
char* Slang::level4(double* result)
{
if(error)
return NULL;
double hold; char* str_value;
str_value = level5(result);
if(*token == '^')
{
get_token();
str_value = level4(&hold); // str_value = !!!!
arith('^', result, &hold);
}
return str_value;
}
//////////////////////////
char* Slang::level5(double* result)
{
if(error)
return NULL;
register char op; char* str_value;
op = 0;
if((token_type == DELIMITER) && *token == '+' || *token == '-')
{
op = *token;
get_token();
}
str_value = level6(result);
if(op)
unary(op, result);
return str_value;
}
////////////////////////////
char* Slang::level6(double* result)
{
if(error)
return NULL;
if((*token == '(') && (token_type == DELIMITER))
{
get_token();
level2(result);
if(*token != ')')
{ serror(1); return NULL; }
get_token();
}
// else
{
return level7(result);
}
}
///////////////////////////
char* Slang::level7(double* result)
{
if(error)
return NULL;
if(*token == '@') // write alse possibility of retusn STR
{
gosub();
*result = variables->find("retval")->d;
get_token();
variable_type = REAL;
return NULL;
}
else
{
if(*prog == '[')
{
// putback();
delete theName;
theName = strdup(token);
get_token(); // '['
get_token(); // index expression
level2(result);
if(*token != ']')
{ serror(19); return NULL; }
// get_token();
token_type = VARIABLE;
strcpy(token, theName);
}
return primitive(result);
}
}
///////////////////////////
char* Slang::primitive(double * result)
{
if(error)
return NULL;
switch(token_type)
{
case VARIABLE:
Variable* v;
v = variables->find(token);
variable_type = v->type;
switch(v->type)
{
case REAL:
*result = v->d;
get_token(); return NULL;
case ARRAY:
*result = v->da[(int)(*result)];
get_token();
return NULL;
case STR :
*result = v->d;
char* str_value = v->s;
get_token();
return str_value;
}
return 0;
case NUMBER:
char* endptr;
*result = strtod(token, &endptr);
get_token();
variable_type = REAL;
return NULL;
case COMMAND:
math(result); get_token(); return NULL;
default:
// serror(0);
return NULL;
}
}
//////////////////////////////
void Slang::arith(char o, double* r, double* h)
{
if(error)
return;
double t, ex;
switch(o)
{
case '-':
*r = *r - *h;
break;
case '+':
*r = *r + *h;
break;
case '*':
*r = *r * *h;
break;
case '/':
*r = (*r) / (*h);
break;
case '%':
t = (*r) / (*h);
*r = *r - (t * (*h));
break;
case '^':
ex = *r;
*r = pow(ex, *h);
break;
}
}
///////////////////////
void Slang::unary(char o, double* r)
{
if(o == '-')
*r = -(*r);
}
/////////////////////////////
void Slang::error_report(char* text) // Overload for your own print
{
printf("%s", text);
}
/////////////////////
void Slang::serror(int err)
{
char c = prog[0]; // Get line number
prog[0] = '\0';
char ln[5];
itoa(nRet(program) + 1, ln, 10);
prog[0] = c;
int l; // line: 10; file: work.vec
char s[160];
char* s1 = s;
strcpy(s1, "line: ");
s1 += 6; // strlen("line: ");
strcpy(s1, ln);
s1 += strlen(ln);
strcpy(s1, "\nfile: ");
s1 += 7;
strcpy(s1, playstack[play_used]->prog);
s1 += strlen(playstack[play_used]->prog);
strcpy(s1, "\n");
s1++;
strcpy(s1, error_string[err]);
error_report(s);
error = 1;
}
//////////////////////////
int Slang::get_token()
{
if(error)
return NULL;
char* temp;
token_type = 0; tok = 0;
temp = token;
if(*prog == '\0')
{
*token = 0;
tok = FINISHED;
return(token_type = DELIMITER);
}
while(iswhite(*prog))
++prog;
if(*prog == '/' && *(prog + 1) == '*' && *prog + 1) // Remarked block
{
while(1)
{
if(*prog == '*' && *(prog + 1) == '/')
{
tok = REMARK_BLOCK;
prog += 2;
return token_type = STRING;
}
else if(!(*(prog + 1))) // End of remarked block
{
tok = FINISHED;
return token_type = DELIMITER;
}
*prog++;
}
}
switch(*prog)
{
case '&':
tok = REMARK;
find_eol();
return(token_type = STRING);
case '@':
tok = GOSUB;
*temp++ = *prog++;
return(token_type = ALPHA);
case '!':
tok = LABEL;
*temp++ = *prog++;
return(token_type = ALPHA);
case ':' :
case '\r':
char c = prog[0];
++prog;
if((*prog != '\0') && (c != ':'))
++prog;
tok = EOL; *token = '\r';
token[1] = '\n'; token[2] = 0;
return(token_type = DELIMITER);
case '"':
prog++;
while(*prog != '"' && *prog != '\r')
*temp++ = *prog++;
if(*prog == '\r')
{ serror(14); return 0; }
prog++; *temp = 0;
return(token_type = QUOTE);
}
if(strchr("<>=", *prog) && strchr("<>=", *(prog + 1)))
{
*temp++ = *prog++;
*temp++ = *prog++;
*temp = 0;
return(token_type = DELIMITER);
}
if(strchr(" +-^/*%=;(),<>[]", *prog))
{
*temp = *prog;
prog++;
temp++;
*temp = 0;
return(token_type = DELIMITER);
}
if(isdigit(*prog))
{
while(!isdelim(*prog))
*temp++ = *prog++;
*temp = '\0';
return(token_type = NUMBER);
}
if(isalpha(*prog))
{
while(!isdelim(*prog))
*temp++ = *prog++;
token_type = STRING;
}
*temp = '\0';
if(token_type == STRING)
{
int i; char* p;
p = token;
while(*p)
{ *p = tolower(*p); p++; }
tok = 0;
for(i = 0; *TABLE[i].command; i++)
if(!strcmp(TABLE[i].command, token))
{ tok = (int)TABLE[i].tok; break; }
if(!tok)
token_type = VARIABLE;
else
token_type = COMMAND;
}
return token_type;
}
////////////////////////////
void Slang::putback()
{
char* t;
t = token;
for(; *t; t++)
prog--;
}
//////////////////////////
int Slang::isdelim(char c)
{
if(strchr(" ;,+-<>/*%^=():[]", c) || c == 9 || c == '\r' || c == 0)
return 1;
return 0;
}
/////////////////////////
int Slang::iswhite(char c)
{
if(c == ' ' || c == '\t')
return 1;
else return 0;
}